package jblip.gui.data.channels;

import java.lang.Thread.State;
import java.util.LinkedList;
import java.util.List;

import jblip.BlipClient;
import jblip.gui.JBlip;
import jblip.resources.Update;

public abstract class UpdatesDataChannel extends DataChannel<Update> {
  private static final long UPDATE_PERIOD = 60000;

  private final Thread updater_thread;

  protected final String channel_id;

  public UpdatesDataChannel(String name) {
    super(name);
    channel_id = name;
    updater_thread = getUpdaterThread();
  }

  public void runUpdaterThread() {
    if (updater_thread.getState() == State.NEW) {
      updater_thread.start();
    }
  }

  private Thread getUpdaterThread() {
    Thread updater = new Thread(new Runnable() {
      private final BlipClient client = JBlip.instance().getBlipClient();

      @Override
      public void run() {
        while (true) {
          final Update last_upd = getLast();
          Iterable<? extends Update> updates;
          if (last_upd == null) {
            updates = getUpdates();
          } else {
            updates = getUpdates(last_upd.getId());
          }

          if (updates != null) {
            List<Update> upd_list = new LinkedList<Update>();
            for (Update update : updates) {
              upd_list.add(0, update);
            }

            if (!upd_list.isEmpty()) {
              items.addAll(upd_list);
              setChanged();
              notifyObservers(upd_list);
            }
          } else {
            System.err.println(client.getLastError());
          }

          synchronized (UpdatesDataChannel.this) {
            try {
              UpdatesDataChannel.this.wait(UPDATE_PERIOD);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    }, "Update thread: " + channel_name);
    updater.setDaemon(true);

    return updater;
  }

  protected abstract Iterable<? extends Update> getUpdates();

  protected abstract Iterable<? extends Update> getUpdates(int last_update_id);
}
